/*
 *  Author: zhaijl 
 *  Url: http://218.1.73.212/down.php
 *  Country: China
 *  
 * ====================================================================
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * ====================================================================
 *
 * This software based apache mina 2.0 and spring 3.0
 *
 */
package org.cloudy.http.mina;

import org.cloudy.http.codec.Response;
import org.cloudy.http.codec.Request;
import org.cloudy.http.codec.Writer;
import org.cloudy.common.spring.SpringContextUtil;
import org.cloudy.http.util.HttpUtil;
import org.cloudy.http.conf.ContextLoader;
import org.cloudy.http.conf.Context;
import org.cloudy.http.mina.Transformimp;  

import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

public class SimpleHandle extends IoHandlerAdapter {
	static Logger logger = Logger.getLogger ( SimpleHandle.class ) ;
	public static final String SAMPLE_HANDLE_ID = "com.matrix.sid" ;
    public void exceptionCaught ( IoSession session, Throwable cause ) 
    	throws Exception {   
    	Response response = ( Response )session.getAttribute ( SimpleHandle.SAMPLE_HANDLE_ID ) ;
    	if ( response != null )  response.filechannelClose () ;
    	session.close ( true ) ; 
    }

    public void messageReceived ( IoSession session, Object message ) 
    	throws Exception { 
    	String htmlError = "system error" ;
    	Request request = ( Request )message ;  
    	Response response = new Response ( request ) ;
    	response.initialize () ; 
    	
    	response.allocate ( ContextLoader.BUFFER_SIZE () ) ;
        response.setResponseCode ( Response.HTTP_STATUS_SUCCESS ) ;
        session.setAttribute ( SimpleHandle.SAMPLE_HANDLE_ID, response ) ;     
    	if ( request != null ) {
			String context = HttpUtil.getContent ( request.getContext () ) ;
    		String classid = ContextLoader.getFilter ( request.getContext () ) ;
			if ( classid != null ) {
				try {
					SimplePlugss simplePlugss = ( SimplePlugss )SpringContextUtil.getBean ( classid ) ;
					response.appendBody ( simplePlugss.doBusiness (  ContextLoader.getContext ( context ), session, request, response ) ) ;
					session.getFilterChain ().fireMessageSent ( new Writer ( response, null, null ) ) ; 
					return ;
				} catch ( Exception exc ) {
					htmlError = exc.getMessage () ;
				}
			} else {
				String fileExt = HttpUtil.getFileext ( request.getContext () ) ;
				String fileName = HttpUtil.getFilename ( request.getContext () ) ;				
				if ( fileName != null && fileExt != null ) {
					Context object = ContextLoader.getContext ( context ) ;
					if ( response.setFileChannel ( ContextLoader.getContextPath ( "/", request.getContext () ) ) != null ) {
						response.buffered ( false ) ;
						response.setContentType ( ContextLoader.getContentType ( fileExt ) ) ;
				        response.setContentLength ( new Long ( response.filechannelSize () - response.filechannelPosition () ).toString () ) ;							    
				        new Transformimp ().doBusiness ( object, session, request, response ) ;
						return ;
					} else htmlError = new StringBuffer ( "file not exist its " ).append ( request.getContext () ).toString () ;	
				} else 	htmlError = new StringBuffer ( "file not exist its " ).append ( request.getContext () ).toString () ;				
			}   	     		    		 
    	} else htmlError = "request error it is null its " ;	

		response.setResponseCode ( Response.HTTP_STATUS_NOT_FOUND ) ;
		response.appendBody ( new StringBuffer ( "<html><body><h1> http server err[" ).append ( Response.HTTP_STATUS_NOT_FOUND ).
				append ( "]:: file[" ).append ( htmlError ).append ( "]</h1></body></html>" ).toString () 
		) ;   		
		session.getFilterChain ().fireMessageSent ( new Writer ( response, null, null ) ) ; 
    }
    
    public void messageSent ( IoSession session, Object message ) throws Exception { 
    	Response response = ( Response )message ; 
    	if ( response == null ) throw new Exception ( "message format err: is null" ) ;
    	if ( response.getWritefuture () != null ) response.getWritefuture ().awaitUninterruptibly () ;
    	
    	if ( response.isBuffered () ) {
    		if ( response.isDelivered () )
    			session.getFilterChain ().fireFilterClose () ; 
    		else {
        		response.setWritefuture ( session.write ( message ) ) ;	
    	        ( ( Response )message ).delivered ( true ) ;    			
    		}	
    	} else if ( response.isDelivered () && response.getFileChannel () != null &&
    			response.filechannelPosition () >= response.filechannelSize () ) {    		
    		session.getFilterChain ().fireFilterClose () ; 
    	} else if ( !response.isDelivered () )  {
    		response.setWritefuture ( session.write ( message ) ) ;	
	        ( ( Response )message ).delivered ( true ) ;
    	} else {
    		if ( response.getFileChannel () != null ) {
				response.resetBody () ;
				response.delivered ( false ) ;
	    		response.setResponseCode ( Response.FILE_STATUS_SUCCESS ) ; 
	            int read_len = response.readBuffer () ;
	            if ( read_len < 0 ) 
	            	session.getFilterChain ().fireFilterClose () ; 
	            else {
	    	    	response.appendBody ( response.bytebufferArray(), 0, read_len );
	    	    	session.getFilterChain ().fireMessageSent ( new Writer ( response, response.getWritefuture(), null ) ) ; 
	            }     			
    		} else session.getFilterChain ().fireFilterClose () ;  
    	}
	}    
    
    public void sessionOpened ( IoSession session ) throws Exception {
    	session.getConfig ().setMinReadBufferSize ( ContextLoader.SERVER_MAXB () ) ;
    	session.getConfig ().setMaxReadBufferSize ( ContextLoader.SERVER_MINB () ) ;
	}    

    public void sessionCreated ( IoSession session ) throws Exception {
    	Response response = ( Response )session.getAttribute ( SimpleHandle.SAMPLE_HANDLE_ID ) ;
    	if ( response != null )  response.filechannelClose () ; 
    }

    public void sessionClosed ( IoSession session ) throws Exception {}
}

